home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 3 / Gold Medal Software - Volume 3 (Gold Medal) (1994).iso / prog / cenvi29.arj / DOS_BOSS.LIB < prev    next >
Text File  |  1994-03-08  |  11KB  |  301 lines

  1. // DOS_Boss.lib - Functions for controlling a windowed DOS session.
  2. // ver.1
  3. //
  4. //
  5. //***** ReadDOSWindow(): Return contents of DOS window in buffer
  6. // SYNTAX: string ReadDOSWindow(int DOSWindowHandle[,int DataLen])
  7. //         string ReadDOSWindow(string WindowTitle[,int DataLen])
  8. // WHERE: DOSWindowHandle: Integer identifier for this window
  9. //        DOSWindowTitle: Partial text title of the window (case-insensitive)
  10. //        DataLen: Length of string returned if not NULL
  11. // RETURN: Returns NULL if failed to read, else returns string containing the
  12. //         contents of the DOS window.
  13. //
  14. //
  15. //***** CopyDOSBufferToLines(): Convert DOS window string to lines
  16. // SYNTAX: string[] CopyDOSBufferToLines(Buffer,LineCount)
  17. // WHERE: Buffer: DOS buffer as returned by ReadDOSWindow()
  18. //        LineCount: Number of lines in the returned array
  19. // RETURN: Returns an array of strings where each element represents
  20. //         the next row of the DOS screen.
  21. //
  22. //
  23. //***** PasteToDOSWindow(): Send characters to a DOS window's keyboard
  24. // SYNTAX: void PasteToDOSWindow(int DOSWindowHandle,string String)
  25. //         void PasteToDOSWindow(string WindowTitle,string String)
  26. // WHERE: DOSWindowHandle: Integer identifier for this window
  27. //        DOSWindowTitle: Partial text title of the window (case-insensitive)
  28. //        String: String of characters to paste into the DOS window
  29. // NOTE: If this function fails after about 15 calls, and won't work again,
  30. //       then call IBM at 1-800-992-4777 and ask for fix for APAR PJ11939.
  31. // new report # 3X128,PSZ
  32. //
  33. //
  34. //**** SendDosKey(): Send keystrokes to DOS window running ServeOS2
  35. // SYNTAX: bool SendDosKey(string ServerSpec,string AsciiBuffer)
  36. //         bool SendDosKey(string ServerSpec,int KeyCode)
  37. //         bool SendDosKey(string ServerSpec,int[] KeyCodes,KeyCount)
  38. //         bool SendDosKey(string ServerSpec,int KeyCode,K_CTRL or K_ALT or K_SHIFT)
  39. // WHERE: ServerSpec: Unique 8.3 name that ServeOS2 was started with
  40. //        AsciiBuffer: Character string to send, will translate to KeyCode
  41. //        KeyCode: ScanCode is high byte, and CharCode is low byte; if not ScanCode
  42. //                 then this function will determine one
  43. //        KeyCodes: An array of ScanCode/CharCode key codes
  44. //        KeyCount: How many keys in the KeyCodes array
  45. //        K_CTRL | K_ALT | K_SHIFT: Use one of these pre-defined values to send code that
  46. //                 this key was held while Key is pressed 
  47. // RETURN: Return True if communication with DOS works, else False
  48. //
  49.  
  50. #define K_CTRL    1
  51. #define K_ALT     2
  52. #define K_SHIFT   3
  53.  
  54. #define K_F1   0x3B00
  55. #define K_F2   0x3C00
  56. #define K_F3   0x3D00
  57. #define K_F4   0x3E00
  58. #define K_F5   0x3F00
  59. #define K_F6   0x4000
  60. #define K_F7   0x4100
  61. #define K_F8   0x4200
  62. #define K_F9   0x4300
  63. #define K_F10  0x4400
  64. #define K_INS  0x5200
  65. #define K_DEL  0x4300
  66. #define K_UP   0x4800
  67. #define K_DOWN 0x5000
  68. #define K_LEFT 0x4B00
  69. #define K_RIGHT 0x4D00
  70. #define K_PGUP 0x4900
  71. #define K_PGDN 0x5100
  72. #define K_END  0x4F00
  73. #define K_HOME 0x4700
  74.  
  75. #define K_ESC  0x011B
  76. #define K_SHIFT_TAB 0x0F00
  77.  
  78.  
  79. #include <WinTools.lib>
  80. #include <ClipBrd.lib>
  81. #include <WinMsg.lib>
  82. #include <FileIO.lib>
  83. #include <NamePipe.lib>
  84.  
  85. ReadDOSWindow(pWindowSpec,pDataLen)
  86. {
  87.    DOSWindowData = NULL;  // assume failure
  88.    _DataLen = 0;
  89.    if ( (lReadHandle = GetWindowHandle(pWindowSpec)) ) {
  90.  
  91.       // Clear the clipboard, so we'll know when new data is here
  92.       PutClipboardData(NULL);
  93.  
  94.       // Send MENU message to the DOS Window to paste all data into the clipboard
  95.       #define WM_SYSCOMMAND      0x0021
  96.       #define CMDSRC_MENU        2
  97.       #define COPY_ALL_COMMAND   0x9E
  98.       WinSendMsg(lReadHandle,WM_SYSCOMMAND,COPY_ALL_COMMAND,CMDSRC_MENU);
  99.  
  100.       if ( NULL != (DOSWindowData = GetClipboardData(CF_TEXT,_DataLen)) )
  101.          _DataLen = strlen(DOSWindowData);
  102.  
  103.    }
  104.    if ( 1 < va_arg() )
  105.       pDataLen = _DataLen;
  106.    return DOSWindowData;
  107. }
  108.  
  109.  
  110. CopyDOSBufferToLines(pBuffer,pLineCount)
  111. {
  112.    for ( _buf = pBuffer, pLineCount = 0; _buf[0];
  113.          pLineCount++, _buf += lStringLen + 1 ) {
  114.       lStringLen = strcspn(_buf,"\n");
  115.       strncpy(_Lines[pLineCount],_buf,lStringLen);
  116.    }
  117.    return _Lines;
  118. }
  119.  
  120.  
  121. PasteToDOSWindow(pWindowSpec,pString)
  122. {
  123.    if ( (lTypeHandle = GetWindowHandle(pWindowSpec)) ) {
  124.  
  125.       // Put the pString data into the clipboard
  126.       PutClipboardData(pString,1+strlen(pString),CF_TEXT);
  127.  
  128.       // Send menu message to paste from the clipboard
  129.       #define PASTE_COMMAND   0x9F
  130.       WinPostMsg(lTypeHandle,WM_SYSCOMMAND,PASTE_COMMAND,CMDSRC_MENU,False);
  131.    }
  132. }
  133.  
  134. AsciiScans = "\x1E\x30\x2E\x20\x12\x21\x22\x23\x17\x24\x25\x26\x32\x31\x18\x19\x10\x13\x1F\x14\x16\x2F\x11\x2D\x15\x2C";
  135. NumberScans = "\x0B\x02\x03\x04\x05\x06\x07\x08\x09\x0A";
  136.  
  137. GetScanCode(pCharCode)
  138. {
  139.    lCharCode = pCharCode;
  140.    if ( 'A' <= toupper(lCharCode)  &&  toupper(lCharCode) <= 'Z' )
  141.       return( AsciiScans[toupper(lCharCode)-'A'] );
  142.    if ( '0' <= lCharCode  &&  lCharCode <= '9' )
  143.       return( NumberScans[lCharCode = '0'] );
  144.    switch ( lCharCode ) {
  145.       case '\r':  return 0x1C;
  146.       case '\t':  return 0x0F;
  147.       case '\b':  return 0x0E;
  148.       case '~':
  149.       case '`':   0x29;
  150.       case '!':   return GetScanCode('1');
  151.       case '@':   return GetScanCode('2');
  152.       case '#':   return GetScanCode('3');
  153.       case '$':   return GetScanCode('4');
  154.       case '%':   return GetScanCode('5');
  155.       case '^':   return GetScanCode('6');
  156.       case '&':   return GetScanCode('7');
  157.       case '*':   return GetScanCode('8');
  158.       case '(':   return GetScanCode('9');
  159.       case ')':   return GetScanCode('0');
  160.       case '_':
  161.       case '-':   return 0x0C;
  162.       case '+':
  163.       case '=':   return 0x0D;
  164.       case '|':
  165.       case '\\':  return 0x2B;
  166.       case '{':
  167.       case '[':   return 0x1A;
  168.       case '}':
  169.       case ']':   return 0x1B;
  170.       case ':'
  171.       case ';'    return 0x27;
  172.       case '\"':
  173.       case '\'':  return 0x28;
  174.       case '<':
  175.       case ',':   return 0x33;
  176.       case '>':
  177.       case '.':   return 0x34;
  178.       case '?':
  179.       case '/':   return 0x35;
  180.       case '\033': return 1;
  181.    }
  182.    return(0);
  183. }
  184.  
  185. SendDosKey(pServerSpec,pKeyCode,pHoldKey)
  186. {
  187.    // Build GSK_Buffer based on type of input
  188.    HoldAKeyDown = ( 2 < va_arg() );
  189.    GSK_Buffer[0] = '\0';   // initialize GSK_Buffer as a byte buffer
  190.    if ( 1 == DataDimension(pKeyCode) ) {
  191.       if ( CMM_BYTE == DataType(pKeyCode) ) {
  192.          // pKeyCode is an ascii string, for all of string add this key code
  193.          // and look up its scan code too
  194.          for ( GSK_BufferLength = 0; pKeyCode[GSK_BufferLength]; GSK_BufferLength++ ) {
  195.             // char code is written first, then scan code
  196.             GSK_Buffer[GSK_BufferLength*2] = pKeyCode[GSK_BufferLength];
  197.             GSK_Buffer[1+(GSK_BufferLength*2)] = GetScanCode(pKeyCode[GSK_BufferLength]);
  198.          }
  199.       } else {
  200.          // this is an array of pkeycode, scancode and charcode
  201.          for ( GSK_BufferLength = 0; GSK_BufferLength < pHoldKey; GSK_BufferLength++ ) {
  202.             // char code is written first, then scan code
  203.             GSK_Buffer[GSK_BufferLength*2] = pKeyCode[GSK_BufferLength] & 0xFF;
  204.             GSK_Buffer[1+(GSK_BufferLength*2)] = (pKeyCode[GSK_BufferLength] >> 8) & 0xFF;
  205.          }
  206.       }
  207.    } else {
  208.       // pKeyCode is a single key if no scan code then must get it
  209.       GSK_BufferLength = 1;
  210.       GSK_CharCode = pKeyCode & 0xFF;
  211.       GSK_ScanCode = (pKeyCode & 0xFF00) >> 8;
  212.       if ( 0 == GSK_ScanCode )
  213.          GSK_ScanCode = GetScanCode(GSK_CharCode);
  214.       if ( HoldAKeyDown ) {
  215.          // adjust keys for pHoldKey
  216.          switch( pHoldKey ) {
  217.             case V_CTRL:
  218.                if ( 'A' <= toupper(GSK_CharCode) && toupper(GSK_CharCode) <= 'Z' )
  219.                   GSK_CharCode -= 'A' - 1;
  220.                else if ( V_F1 <= pKeyCode  &&  pKeyCode <= V_F10 )
  221.                   GSK_ScanCode += 0x23;
  222.                else {
  223.                   switch ( GSK_ScanCode ) {
  224.                      case K_LEFT:  GSK_ScanCode = 0x73; break;
  225.                      case K_RIGHT: GSK_ScanCode = 0x74; break;
  226.                      case K_PGUP:  GSK_ScanCode = 0x84; break;
  227.                      case K_PGDN:  GSK_ScanCode = 0x76; break;
  228.                      case K_END:   GSK_ScanCode = 0x77; break;
  229.                      case K_HOME:  GSK_ScanCode = 0x75; break;
  230.                   }
  231.                }
  232.                break;
  233.             V_ALT:
  234.                if ( 'A' <= toupper(GSK_CharCode) && toupper(GSK_CharCode) <= 'Z' )
  235.                   GSK_CharCode = 0;
  236.                else if ( V_F1 <= pKeyCode  &&  pKeyCode <= V_F10 )
  237.                   GSK_ScanCode += 0x2D;
  238.                else if ( 0x02 <= ScanCode  &&  ScanCode <= 0x0D )
  239.                   GSK_ScanCode += 0x76, GSK_CharCode = 0;
  240.                break;
  241.             V_SHIFT:
  242.                if ( islower(GSK_CharCode) )
  243.                   GSK_CharCode = toupper(GSK_CharCode);
  244.                else if ( V_F1 <= pKeyCode  &&  pKeyCode <= V_F10 )
  245.                   GSK_ScanCode += 0x19;
  246.                break;
  247.             default:
  248.                printf("\aHoldKey = %d unknown!\a\n",pHoldKey); abort();
  249.          }
  250.       }
  251.       GSK_Buffer[0] = GSK_CharCode;
  252.       GSK_Buffer[1] = GSK_ScanCode;
  253.    }
  254.    return ( 0 == GSK_BufferLength  ||  255 < GSK_BufferLength )
  255.         ? False
  256.         : SendKeyBufferToServer(pServerSpec,GSK_Buffer,GSK_BufferLength) ;
  257. }
  258.  
  259.  
  260. SendKeyBufferToServer(PipeName,Buffer,BufferLen/*max 255*/)
  261. {
  262.    bool success = False;   // assume failure
  263.    sprintf(GSFullName,"\\PIPE\\%s",PipeName);
  264.  
  265.    if ( !DosCreateNPipe(GSFullName,GSPipeHandle,
  266.                         NP_ACCESS_DUPLEX | NP_NOINHERIT,
  267.                         NP_NOWAIT | NP_TYPE_BYTE | NP_UNLIMITED_INSTANCES | NP_READMODE_BYTE,
  268.                         4096, 0, 0) ) {
  269.       // Give the DOS program up to 10 seconds to open the file
  270.       for ( GSrepeat =  10 * 10; GSRepeat--; ) {
  271.          suspend(100);
  272.          if ( !DosConnectNPipe(GSPipeHandle) ) {
  273.             success = True;
  274.             break;
  275.          }
  276.       }
  277.       if ( success ) {
  278.  
  279.          // change pipe to blocking state to make sure reads and writes are
  280.          // finished
  281.          DosSetNPHState(GSPipeHandle,NP_WAIT | NP_READMODE_BYTE);
  282.  
  283.          _SendBuf[0] = byte(BufferLen);
  284.          memcpy(_SendBuf+1,Buffer,2*BufferLen);
  285.          if ( DosWrite(GSPipeHandle,_SendBuf,2*BufferLen+1,GSBytesSent)
  286.            || GSBytesSent != 2*BufferLen+1 ) {
  287.             success = False;
  288.          } else {
  289.             // Will be finished when DOS closes the file, which will
  290.             // break the pipe.  A READ will hang until pipe is broken.
  291.             GSDummyBuf[0] = '\0';
  292.             DosRead(GSPipeHandle,GSDummyBuf,1,GSByteRead);
  293.          }
  294.          DosDisconnectNPipe(GSPipeHandle);
  295.       }
  296.       DosClose(GSPipeHandle);
  297.    }
  298.    return(success);
  299. }
  300.  
  301.